package com.xhwl.logistics.service.logistics.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.xhwl.common.pojo.ResultJson;
import com.xhwl.logistics.converter.mapstruct.logistics.ApprovalNodeConverter;
import com.xhwl.logistics.converter.mapstruct.logistics.ApprovalProcessConverter;
import com.xhwl.logistics.entity.approval.ApprovalNode;
import com.xhwl.logistics.entity.approval.ApprovalNodeUser;
import com.xhwl.logistics.entity.approval.ApprovalProcess;
import com.xhwl.logistics.dao.mapper.logistics.ApprovalProcessMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xhwl.logistics.entity.logistics.VisitorRecord;
import com.xhwl.logistics.enums.logistics.ApprovalProcessTypeEnum;
import com.xhwl.logistics.enums.logistics.ApprovalStatusEnum;
import com.xhwl.logistics.logistics.request.ApprovalProcessParam;
import com.xhwl.logistics.logistics.request.DeleteAprovalParam;
import com.xhwl.logistics.query.ApprovalQuery;
import com.xhwl.logistics.service.logistics.IApprovalNodeService;
import com.xhwl.logistics.service.logistics.IApprovalNodeUserService;
import com.xhwl.logistics.service.logistics.IApprovalProcessService;
import com.xhwl.logistics.service.logistics.IVisitorRecordService;
import com.xhwl.logistics.vo.logistics.approval.ApprovalNodeVO;
import com.xhwl.logistics.vo.logistics.approval.ApprovalProcessVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * <p>
 * 审批流程表 服务实现类
 * </p>
 *
 * @author lin.yang
 * @since 2023-12-26
 */
@Service
@Slf4j
public class ApprovalProcessServiceImpl extends ServiceImpl<ApprovalProcessMapper, ApprovalProcess> implements IApprovalProcessService {


    @Autowired
    private IApprovalNodeUserService approvalNodeUserService;

    @Autowired
    private IApprovalNodeService approvalNodeService;

    @Autowired
    private IVisitorRecordService visitorRecordService;


    @Override
    @Transactional
    public ResultJson saveOrUpdateApprovalInfo(ApprovalProcessParam param) {
        Integer processId =Optional.ofNullable( param.getProcessId()).orElse(null);
        //判断是否关联了未完全处理的业务
        if (ObjectUtil.isNotNull(processId)) {
            LambdaQueryWrapper<VisitorRecord> queryWrapper = Wrappers.lambdaQuery();
            queryWrapper.eq(VisitorRecord::getFlowId,processId);
            queryWrapper.eq(VisitorRecord::getStatus, ApprovalStatusEnum.WAITING_APPROVAL.getCode());
            List<VisitorRecord> visitorRecords = Optional.ofNullable(this.visitorRecordService.list(queryWrapper)).orElse(Collections.emptyList());
            if (visitorRecords.size()>0) {
                return ResultJson.fail("对应的流程关联了未审批的业务操作，不能进行流程编辑操作");
            }
        }
        log.info("saveOrUpdateApprovalInfo() called with parameters => 【param = {}】",param);
        ApprovalProcess approvalProcess = ApprovalProcessConverter.INSTANCE.toPoConvert(param);
        if (ObjectUtil.isNull(approvalProcess.getCreatedTime())) {
            approvalProcess.setCreatedTime(new Date());
        }
        //更新时间
        if (ObjectUtil.isNull(approvalProcess.getUpdatedTime())) {
            approvalProcess.setUpdatedTime(new Date());
        }
        //默认的流程为物流流程
        if (ObjectUtil.isNull(approvalProcess.getProcessType())) {
            approvalProcess.setProcessType(String.valueOf(ApprovalProcessTypeEnum.Logistics.getCode()));
            approvalProcess.setProcessTypeName(ApprovalProcessTypeEnum.Logistics.getVal());
        }

        //获取审批流程节点列表
        List<ApprovalNodeVO> approvalNodeList = Optional.ofNullable(param).map(x -> x.getApprovalNodeList()).orElse(Collections.emptyList());
        //转换为审批流数据
        LambdaQueryWrapper<ApprovalProcess> queryWrapperProcess = Wrappers.lambdaQuery();
        //有效未删除的流程只保存一个
        queryWrapperProcess.eq(ApprovalProcess::getLogicDel,"0");
        List<ApprovalProcess> existList = this.list(queryWrapperProcess);
        //get not deleted approval_process
        if (existList.size()>0) {
            //1、是否关联了未处理的完成的流程业务
            Integer id = existList.get(0).getProcessId();
            param.setProcessId(id);
            approvalProcess.setProcessId(id);
            LambdaQueryWrapper<VisitorRecord> queryWrapper = Wrappers.lambdaQuery();
            queryWrapper.eq(VisitorRecord::getFlowId,id);
            //待审批 已通过的状态
            queryWrapper.in(VisitorRecord::getStatus,ApprovalStatusEnum.WAITING_APPROVAL,ApprovalStatusEnum.PASS_APPROVAL);
            List<VisitorRecord> list =Optional.ofNullable(visitorRecordService.list(queryWrapper)).orElse(Collections.emptyList());
            if (list.size()>0) {
                return ResultJson.fail(String.format("存在未处理完成的物流业务：司机姓名：%s",list.get(0).getDriverName()));
            }
        }else{
            //一个有效流程都没有完全新增
            this.saveOrUpdate(approvalProcess);
            for (ApprovalNodeVO approvalNodeVO : approvalNodeList) {
                approvalNodeVO.setProcessId(approvalProcess.getProcessId());
                //保存节点
                ApprovalNode approvalNode = ApprovalNodeConverter.INSTANCE.toPoConvert(approvalNodeVO);
                this.approvalNodeService.saveOrUpdate(approvalNode);
                for (ApprovalNodeUser approvalNodeUser : approvalNodeVO.getNodeUserList()) {
                    approvalNodeUser.setApprovalNodeId(approvalNode.getNodeId());
                    this.approvalNodeUserService.saveOrUpdate(approvalNodeUser);
                }
            }
            return ResultJson.success();
        }

        //保存审批流程表数据
        this.saveOrUpdate(approvalProcess);

        //获取当前流程的id
        ApprovalQuery approvalQuery = new ApprovalQuery();
        approvalQuery.setProcessId(approvalProcess.getProcessId());
        //已经存在的流程
        ApprovalProcessVO existApprovalProcessVO = Optional.ofNullable(this.detailApprovalInfo(approvalQuery)).map(x -> x.getResult()).orElse(null);
        if (approvalNodeList.size() > 0) {

            List<String> newNodeIdList = approvalNodeList.stream().map(x -> x.getNodeId()).collect(Collectors.toList());
            List<String> existNodeIdList = existApprovalProcessVO.getApprovalNodeList().stream().map(x -> x.getNodeId()).collect(Collectors.toList());
            List<String> noNodeId = existNodeIdList.stream().filter(s -> !newNodeIdList.contains(s)).collect(Collectors.toList());
            this.approvalNodeService.removeByIds(noNodeId);
            //遍历每一个节点
            for (int i = 0; i < approvalNodeList.size(); i++) {
                ApprovalNodeVO approvalNodeVO = approvalNodeList.get(i);
                approvalNodeVO.setProcessId(approvalProcess.getProcessId());
                //节点所属层级
                approvalNodeVO.setNodeLevel(i);
                ApprovalNode approvalNode = ApprovalNodeConverter.INSTANCE.toPoConvert(approvalNodeVO);
                if (ObjectUtil.isNull(approvalNode.getCreatedTime())) {
                    approvalNode.setCreatedTime(new Date());
                }
                //获取节点对应的成员信息
                List<ApprovalNodeUser> approvalNodeUserList = Optional.ofNullable(approvalNodeVO).map(x -> x.getNodeUserList()).orElse(Collections.emptyList());
                //保存节点
                approvalNodeService.saveOrUpdate(approvalNode);
                ApprovalNodeVO existeApprovalNodeVO = existApprovalProcessVO.getApprovalNodeList().stream()
                        .filter(x -> x.getNodeId().equalsIgnoreCase(approvalNodeVO.getNodeId())).findFirst().orElse(null);
                if (!ObjectUtil.isNull(existeApprovalNodeVO)) {
                    //编辑节点
                    List<Integer> userIdList = existeApprovalNodeVO.getNodeUserList().stream().map(x -> x.getId()).collect(Collectors.toList());
                    List<Integer> newUserIdList = approvalNodeUserList.stream().map(x -> x.getId()).collect(Collectors.toList());
                    List<Integer> noUserId = userIdList.stream().filter(x -> !newUserIdList.contains(x)).collect(Collectors.toList());
                    if (noUserId.size()>0) {
                        //删除该用户
                        this.approvalNodeUserService.removeByIds(noUserId);
                    }
                }
                if (approvalNodeUserList.size() > 0) {
                    approvalNodeUserList.forEach(x -> {
                        x.setApprovalNodeId(approvalNode.getNodeId());
                    });
                    approvalNodeUserService.saveOrUpdateBatch(approvalNodeUserList);
                }
            }
        }
        return ResultJson.success();
    }

    /**
     * 获取流程详情信息
     * @param query
     * @return
     */
    @Override
    public ResultJson<ApprovalProcessVO> detailApprovalInfo(ApprovalQuery query) {
        log.info("detailApprovalInfo() called with parameters => 【query = {}】",query);
        ApprovalProcessVO vo=new ApprovalProcessVO();
        Integer processId = Optional.ofNullable(query).map(x -> x.getProcessId()).orElse(null);
        String logicDel = Optional.ofNullable(query).map(x -> x.getLogicDel()).orElse("0");
        LambdaQueryWrapper<ApprovalProcess> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(ObjectUtil.isNotNull(processId),ApprovalProcess::getProcessId,processId);
        queryWrapper.in(ObjectUtil.isNotNull(logicDel),ApprovalProcess::getLogicDel,logicDel);
        //if (ObjectUtil.isNotNull(processId)) {
            ApprovalProcess approvalProcess = Optional.ofNullable(this.getBaseMapper().selectOne(queryWrapper)).orElse(null);
            if (ObjectUtil.isNotNull(approvalProcess)) {
                vo = ApprovalProcessConverter.INSTANCE.toVoConvert(approvalProcess);
                //获取节点信息
                LambdaQueryWrapper<ApprovalNode> wrapperQuery = Wrappers.lambdaQuery();
                wrapperQuery.eq(ApprovalNode::getProcessId,approvalProcess.getProcessId());
                //流程节点按照时间来正序排序
                wrapperQuery.orderByAsc(ApprovalNode::getCreatedTime);
                List<ApprovalNode> approvalNodeList = Optional.ofNullable(this.approvalNodeService.list(wrapperQuery)).orElse(Collections.emptyList());
                if (approvalNodeList.size()>0) {
                    List<ApprovalNodeVO> approvalNodeVOS = ApprovalNodeConverter.INSTANCE.toVoConvertList(approvalNodeList);

                    for (ApprovalNodeVO approvalNodeVO : approvalNodeVOS) {
                        String nodeId =Optional.ofNullable(approvalNodeVO.getNodeId()).orElse(null);
                        if (ObjectUtil.isNotNull(nodeId)) {
                            //获取节点下对应的用户信息
                            LambdaQueryWrapper<ApprovalNodeUser> nodeUserLambdaQueryWrapper = Wrappers.lambdaQuery();
                            nodeUserLambdaQueryWrapper.eq(ApprovalNodeUser::getApprovalNodeId,nodeId);
                            List<ApprovalNodeUser> approvalNodeUsers = Optional.ofNullable(this.approvalNodeUserService.list(nodeUserLambdaQueryWrapper)).orElse(Collections.emptyList());
                            approvalNodeVO.setNodeUserList(approvalNodeUsers);
                        }
                    }
                    vo.setApprovalNodeList(approvalNodeVOS);
                }
            }
        //}
        return ResultJson.success(vo);
    }


    @Override
    public ResultJson deleteApprovalNode(DeleteAprovalParam params) {
        String processId = Optional.ofNullable(params).map(x -> x.getProcessId()).orElse(null);
        ApprovalProcess approvalProcess = this.getBaseMapper().selectById(processId);
        LambdaQueryWrapper<VisitorRecord> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(VisitorRecord::getFlowId,params.getProcessId());
        //待审批 + 已预约通过
        queryWrapper.in(VisitorRecord::getStatus,ApprovalStatusEnum.WAITING_APPROVAL.getCode(),ApprovalStatusEnum.PASS_APPROVAL.getCode());
        List<VisitorRecord> list = this.visitorRecordService.list(queryWrapper);
        if (list.size()>0) {
            return ResultJson.fail("该流程关联了未完成的业务，不能删除");
        }
        //获取所有的节点列表
        List<ApprovalNode> approvalNodes = approvalNodeService.listByIds(params.getNodeIds());
        approvalNodeService.removeByIds(params.getNodeIds());
        //同时删除对应的节点下的用户信息
        List<String> nodeIdList = approvalNodes.stream().map(x -> x.getNodeId()).collect(Collectors.toList());
        approvalNodeUserService.removeByIds(nodeIdList);
        return ResultJson.success();
    }

    @Override
    public ResultJson listApprovalProcess(ApprovalQuery query) {

        log.info("listApprovalProcess() called with parameters => 【query = {}】",query);
        LambdaQueryWrapper<ApprovalProcess> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.like(ObjectUtil.isNotNull(query.getProcessName()),ApprovalProcess::getProcessName,query.getProcessName());
        queryWrapper.eq(ObjectUtil.isNotNull(query.getProcessId()),ApprovalProcess::getProcessId,query.getProcessId());
        List<ApprovalProcess> list = this.list(queryWrapper);
        return ResultJson.success(list);
    }
}
